from django.shortcuts import render
from django.contrib.admin.views.decorators import staff_member_required
from django.views.generic import View
from django.views.decorators.http import require_POST,require_GET
from apps.news.models import NewsCategory,News,Banner
from utils import restful
from .forms import EditNewsCategoryForm,EditNewsForm
import os
from django.conf import settings
import qiniu
from apps.cms.forms import WriteNewsForm,AddBannerForm,EditBannerForm
from apps.news.serializers import BannerSerializer
from django.core.paginator import Paginator
from datetime import datetime
from django.utils.timezone import make_aware
from urllib import parse


@staff_member_required(login_url='index')
def index(request):
    return render(request,'cms/index.html')

class WriteNewsView(View):
    def get(self,request):
        categories = NewsCategory.objects.all()
        context = {
            'categories': categories
        }
        return render(request, '../../front/templates/cms/cms_write_news.html', context=context)

    def post(self,request):
        form = WriteNewsForm(request.POST)
        if form.is_valid():
            title = form.cleaned_data.get('title')
            desc = form.cleaned_data.get('desc')
            thumbnail = form.cleaned_data.get('thumbnail')
            content = form.cleaned_data.get('content')
            category_id = form.cleaned_data.get('category')
            category = NewsCategory.objects.get(pk=category_id)
            News.objects.create(title=title,desc=desc,thumbnail=thumbnail,category=category,author=request.user,content=content)
            return restful.ok()
        else:
            return restful.params_error(message=form.get_errors())



@require_GET
def news_category(request):
    # 获取所有的新闻分类，发送给前端
    categories = NewsCategory.objects.all()
    context = {
        'categories':categories
    }
    return render(request, '../../front/templates/cms/cms_news_category.html', context=context)

@require_POST
def add_news_category(request):
    name = request.POST.get('name')
    exists = NewsCategory.objects.filter(name=name).exists()
    if not exists:
        NewsCategory.objects.create(name=name)
        return restful.ok()
    else:
        return restful.params_error("您输入的分类已经存在！")

@require_POST
def edit_news_category(request):
    form = EditNewsCategoryForm(request.POST)
    if form.is_valid():
        pk = form.cleaned_data.get('pk')
        name = form.cleaned_data.get('name')
        try:
            NewsCategory.objects.filter(pk=pk).update(name=name)
            return restful.ok()
        except:
            return restful.params_error(message='该分类不存在！')
    else:
        return restful.params_error(message=form.get_error())

@require_POST
def delete_news_category(request):
    # 获取前端传过来的PK的值
    pk = request.POST.get('pk')
    try:
        NewsCategory.objects.filter(pk=pk).delete()
        return restful.ok()
    except:
        return restful.params_error(message='该分类不存在！')

@require_POST
def upload_file(request):
    file = request.FILES.get('file')
    name = file.name
    # 以二进制写的方式打开
    with open(os.path.join(settings.MEDIA_ROOT,name),'wb') as fp:
        for chunk in file.chunks():
            fp.write(chunk)
        # 获取图片的绝对路径:http://127.0.0.1:9000/media/111.jpg
    url = request.build_absolute_uri(settings.MEDIA_URL+name)
    return restful.result(data={'url':url})

@require_GET
def qntoken(request):
    access_key = settings.QINIU_ACCESS_KEY
    secret_key = settings.QINIU_SECRET_KEY
    # 片区名称
    bucket = settings.QINIU_BUCKET_NAME
    # 登录并验证两个KEY
    q = qiniu.Auth(access_key,secret_key)
    # 保存发送的文件到相应的片区里
    token = q.upload_token(bucket)
    return restful.result(data={'token':token})

def banners(request):
    return render(request,'news/banners.html')

def banner_list(request):
    banners = Banner.objects.all()
    serializer = BannerSerializer(banners,many=True)
    return restful.result(data=serializer.data)

def add_banner(request):
    form = AddBannerForm(request.POST)
    if form.is_valid():
        priority = form.cleaned_data.get('priority')
        image_url = form.cleaned_data.get('image_url')
        link_to = form.cleaned_data.get('link_to')
        banner = Banner.objects.create(priority=priority,image_url=image_url,link_to=link_to)
        return restful.result(data={'banner_id': banner.priority})
    else:
        return restful.params_error(message=form.get_errors())

def delete_banner(request):
    bannerId = request.POST.get('banner_id')
    Banner.objects.filter(pk=bannerId).delete()
    return restful.ok()

def edit_banner(request):
    form = EditBannerForm(request.POST)
    if form.is_valid():
        pk = form.cleaned_data.get('pk')
        priority = form.cleaned_data.get('priority')
        image_url = form.cleaned_data.get('image_url')
        link_to = form.cleaned_data.get('link_to')
        Banner.objects.filter(pk=pk).update(priority=priority,image_url=image_url,link_to=link_to)
        return restful.ok()
    else:
        return restful.params_error(message=form.get_errors())

class NewsListView(View):
    def get(self,request):
        page = int(request.GET.get('p',1))
        start = request.GET.get("start")
        end = request.GET.get('end')
        title = request.GET.get('title')
        category_id = int(request.GET.get('category',0))
        newses = News.objects.select_related('category','author').all()
        if start or end:
            if start:
                start_date = datetime.strptime(start,'%Y/%m/%d')
            else:
                start_date = datetime(year=2019,month=1,day=1)
            if end:
                end_date = datetime.strptime(end,'%Y/%m/%d')
            else:
                end_date = datetime.now()
            # 增加时间条件查询，make_aware()能将幼稚的时间改成清醒的时间
            newses = newses.filter(pub_time__range=(make_aware(start_date),make_aware(end_date)))

        if title:
            # 增加标题查询，不区分大小写
            newses = newses.filter(title__icontains=title)
        if category_id:
            newses = newses.filter(category=category_id)
        # 后面的2表示每页只显示2条数据
        paginator = Paginator(newses,5)
        page_obj = paginator.page(page)
        context_data = self.get_pagination_data(paginator,page_obj)
        context = {
            'categories':NewsCategory.objects.all(),
            'newses':page_obj.object_list,
            'page_obj':page_obj,
            'paginator':paginator,
            'start':start,
            'end':end,
            'title':title,
            'category_id':category_id,
            'url_query':'&'+parse.urlencode({
                'start':start or "",
                'end':end or '',
                'title':title or '',
                'category':category_id or ''
            })
        }
        context.update(context_data)
        return render(request,'cms/news_list.html',context=context)

    def get_pagination_data(self, paginator, page_obj, around_count=2):
        current_page = page_obj.number
        num_pages = paginator.num_pages

        left_has_more = False
        right_has_more = False

        if current_page <= around_count + 2:
            left_pages = range(1, current_page)
        else:
            left_has_more = True
            left_pages = range(current_page - around_count, current_page)

        if current_page >= num_pages - around_count - 1:
            right_pages = range(current_page + 1, num_pages + 1)
        else:
            right_has_more = True
            right_pages = range(current_page + 1, current_page + around_count + 1)

        return {
            # left_pages：代表的是当前这页的左边的页的页码
            'left_pages': left_pages,
            # right_pages：代表的是当前这页的右边的页的页码
            'right_pages': right_pages,
            'current_page': current_page,
            'left_has_more': left_has_more,
            'right_has_more': right_has_more,
            'num_pages': num_pages
        }

class EditNewsView(View):
    def get(self,request):
        news_id = request.GET.get('news_id')
        news = News.objects.get(pk=news_id)
        context = {
            'news':news,
            'categories':NewsCategory.objects.all()
        }
        return render(request,'cms/cms_write_news.html',context=context)
    def post(self,request):
        form = EditNewsForm(request.POST)
        if form.is_valid():
            title = form.cleaned_data.get('title')
            desc = form.cleaned_data.get('desc')
            thumbnail = form.cleaned_data.get('thumbnail')
            content = form.cleaned_data.get('content')
            category_id = form.cleaned_data.get('category')
            category = NewsCategory.objects.get(pk=category_id)
            pk = form.cleaned_data.get('pk')
            News.objects.filter(pk=pk).update(title=title,desc=desc,thumbnail=thumbnail,content=content,category=category)
            return restful.ok()
        else:
            return restful.params_error(message=form.get_errors())
@require_POST
def delete_news(request):
    news_id = request.POST.get('news_id')
    news = News.objects.filter(pk=news_id).delete()
    return restful.ok()